//
// Created by 86134 on 2024/1/18.
//

#ifndef SOCKET_CONNECTION_H
#define SOCKET_CONNECTION_H

#include "TcpBuffer.hpp"

#include <string>
#include <functional>
#include <memory>
#include <sys/epoll.h>
#include <vector>

namespace DBServer {
namespace Socket {
    
typedef struct SocketInfo {
    short port;
    std::string ip;
} SocketInfo;

class Connection {
public:
    typedef std::function<std::string(std::string&&)> CallBack;

    Connection();
    ~Connection();
    
    // pure virtual function
    // differernt son class have diffevent immpelements
    virtual int create_socket() = 0;
    int close_socket();

    // set the attribution of the socket
    int set_so_reuse();
    int set_so_unblock();

    // configures the connection
    void set_socket_fd(int);
    void set_logic_cb(std::function<std::string(std::string&&)>);
    void set_epoll_fd(int);
    void set_socket_status(int);
    void set_socket_info(std::string&&, int);
    void set_epoll_event();

    // get the infomation of the connection
    std::unique_ptr<SocketInfo> get_socket_info();
    int get_socket_fd();
    int get_socket_status();
    struct epoll_event* get_epoll_event();
    TcpBuffer* get_buff();
    std::function<std::vector<std::shared_ptr<Request>>(int, int&)> get_read_cb();
    std::function<std::string(std::string&&)> get_logic_cb();
    std::function<int(int)> get_write_cb();

private:
    // connection configure
    using read_cb_t = std::function<std::vector<std::shared_ptr<Request>>(int fd, int &ret)>;
    using write_cb_t = std::function<int(int)>;
    using logic_cb_t = std::function<std::string(std::string &&)>;

    int                                             socket_fd;
    int                                             socket_status;
    SocketInfo                                      *socket_info;
    // event cb
    write_cb_t                                      write_cb;
    read_cb_t                                       read_cb;
    logic_cb_t                                      logic_func;
    // tcp io buffer
    TcpBuffer                                       *tcp_buffer;
    // reacotr bending
    int                                             epoll_fd;
    struct epoll_event                              event;
};

class ServerConn : public Connection {
public:
    int create_socket(int listen_fd);

private:
    int create_socket() { return 0; }
};

class ClientConn : public Connection {
public:
    ClientConn() = default;
    ~ClientConn() = default;
    int create_socket();
};

class Listener : public Connection {
public:
    int create_socket();
};

}   
}

#endif //SOCKET_CONNECTION_H